package hn.cch.security.configuration;


import hn.cch.security.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders
        .AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration
        .WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.rememberme
        .JdbcTokenRepositoryImpl;

import javax.sql.DataSource;

/**
 * @author CCH
 * @version 2018.09.21
 */
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {


    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsServiceImpl userDetailsServiceImpl;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws
            Exception {
        auth.userDetailsService(userDetailsServiceImpl).passwordEncoder
                (bCryptPasswordEncoder());

        auth.eraseCredentials(false);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.formLogin().loginPage("/login").permitAll().successHandler
                (successHandler())

                .and().authorizeRequests().antMatchers("/images/**",
                "/scripts/**", "/styles/**", "/checkcode").permitAll()
                .anyRequest().authenticated()

                .and().csrf().requireCsrfProtectionMatcher
                (csrfProtectionMatcher())

                .and().sessionManagement().sessionCreationPolicy
                (SessionCreationPolicy.NEVER).

                and().logout().logoutSuccessUrl("/login")

                .and().exceptionHandling().accessDeniedPage("/deny")
                //保存登陆
                .and().rememberMe().tokenValiditySeconds(86400)//86400:一天
                .tokenRepository(jdbcTokenRepository());
    }


    @Bean
    public SuccessHandler successHandler() {
        return new SuccessHandler();
    }

    @Bean
    public DecisionManager decisionManager() {
        return new DecisionManager();
    }

    @Bean
    public CsrfProtectionMatcher csrfProtectionMatcher() {
        return new CsrfProtectionMatcher();
    }


    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }


    @Bean
    public JdbcTokenRepositoryImpl jdbcTokenRepository() {
        JdbcTokenRepositoryImpl jdbcTokenRepository = new
                JdbcTokenRepositoryImpl();
        jdbcTokenRepository.setDataSource(dataSource);
        return jdbcTokenRepository;
    }


    @Bean
    public FilterSecurityInterceptor filterSecurityInterceptor() throws
            Exception {
        FilterSecurityInterceptor filterSecurityInterceptor = new
                FilterSecurityInterceptor();
        filterSecurityInterceptor.setAuthenticationManager
                (authenticationManager);
        filterSecurityInterceptor.setFilterInvocationSecurityMetadataSource(new
                SecurityMetadataSource());
        filterSecurityInterceptor.setAccessDecisionManager(decisionManager());
        return filterSecurityInterceptor;
    }


}
